package com.czp.infosharingplatformapp.service.impl;

import com.czp.infosharingplatformapp.model.*;
import com.czp.infosharingplatformapp.repository.PostRepository;
import com.czp.infosharingplatformapp.repository.UserRepository;
import com.czp.infosharingplatformapp.service.RecommendationService;
import com.czp.infosharingplatformapp.service.UserPostRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.czp.infosharingplatformapp.util.SimilarityUtil.computeCosineSimilarity;

import java.util.*;


@Service
public class RecommendationServiceImpl implements RecommendationService {

    @Autowired
    private UserPostRecordService userPostRecordService;

    @Autowired
    private PostRepository postRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public List<Post> recommendPostsForUser(Long userId) {
        // Step 1: 获取当前用户的标签偏好和分类偏好
        Map<String, Integer> currentUserTagPreferences = userPostRecordService.computeUserTagPreferences(userId);
        Map<String, Integer> currentUserCategoryPreferences = userPostRecordService.computeUserCategoryPreferences(userId);

        // 打印当前用户的标签和分类偏好
        logPreferences(currentUserTagPreferences, currentUserCategoryPreferences);

        // Step 2: 查找所有用户，并计算兴趣相似度
        List<User> allUsers = userRepository.findAll();
        Map<Long, Double> userSimilarity = new HashMap<>();

        for (User otherUser : allUsers) {
            if (!otherUser.getId().equals(userId)) {
                Map<String, Integer> otherUserTagPreferences = userPostRecordService.computeUserTagPreferences(otherUser.getId());
                Map<String, Integer> otherUserCategoryPreferences = userPostRecordService.computeUserCategoryPreferences(otherUser.getId());

                // 计算标签相似度和分类相似度
                double tagSimilarity = computeCosineSimilarity(currentUserTagPreferences, otherUserTagPreferences);
                double categorySimilarity = computeCosineSimilarity(currentUserCategoryPreferences, otherUserCategoryPreferences);

                // 综合相似度 (可以根据需要调整权重)
                double overallSimilarity = (tagSimilarity + categorySimilarity) / 2;
                userSimilarity.put(otherUser.getId(), overallSimilarity);
            }
        }

        // Step 3: 推荐相似用户喜欢的帖子
        final double SIMILARITY_THRESHOLD = 0.5; // 假设相似度超过 0.5 才推荐
        List<Post> recommendations = new ArrayList<>();

        for (Map.Entry<Long, Double> entry : userSimilarity.entrySet()) {
            if (entry.getValue() < SIMILARITY_THRESHOLD) {
                continue;
            }
            Long similarUserId = entry.getKey();
            List<UserPostRecord> similarUserRecords = userPostRecordService.getUserRecords(similarUserId);

            for (UserPostRecord record : similarUserRecords) {
                Post post = postRepository.findById(record.getPostId()).orElse(null);
                if (post != null && !recommendations.contains(post)) {
                    recommendations.add(post);
                }
            }
        }

        // Step 4: 添加当前用户喜欢的帖子
        final int PREFERENCE_THRESHOLD = 5; // 假设喜爱值超过 5 才推荐
        List<Post> allPosts = postRepository.findAll();

        // 根据标签偏好推荐
        for (Map.Entry<String, Integer> entry : currentUserTagPreferences.entrySet()) {
            if (entry.getValue() < PREFERENCE_THRESHOLD) {
                continue;
            }
            String preferredTag = entry.getKey();
            for (Post post : allPosts) {
                List<PostTag> postTags = post.getTags(); // 获取帖子的标签对象集合
                for (PostTag postTag : postTags) {
                    if (!postTag.getTag().equals(preferredTag)) {
                        continue;
                    }
                    if (!recommendations.contains(post)) {
                        recommendations.add(post);
                        break; // 标签匹配后跳出内层循环
                    }
                }
            }
        }
        // 根据分类偏好推荐
        for (Map.Entry<String, Integer> entry : currentUserCategoryPreferences.entrySet()) {
            if (entry.getValue() < PREFERENCE_THRESHOLD) {
                continue;
            }
            String preferredCategory = entry.getKey();
            for (Post post : allPosts) {
                if (!post.getCategory().getName().equals(preferredCategory)) {
                    continue;
                }
                if (!recommendations.contains(post)) {
                    recommendations.add(post);
                    break; // 分类匹配后跳出内层循环
                }
            }
        }
        return recommendations;
    }

    // 用于打印用户偏好的辅助方法
    private void logPreferences(Map<String, Integer> tagPreferences, Map<String, Integer> categoryPreferences) {
        System.out.println("--------------------***********---------------------");
        System.out.println("当前用户的标签偏好:");
        for (Map.Entry<String, Integer> entry : tagPreferences.entrySet()) {
            System.out.println("Tag: " + entry.getKey() + ", Preference: " + entry.getValue());
        }
        System.out.println("当前用户的分类偏好:");
        for (Map.Entry<String, Integer> entry : categoryPreferences.entrySet()) {
            System.out.println("Category: " + entry.getKey() + ", Preference: " + entry.getValue());
        }
        System.out.println("--------------------***********---------------------");
    }
}